package com.kevms.phonewars;

import java.util.List;

import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

/** 
* @class Combat
* 
* @brief Activity used to display the combat screen while in a match.
* 
* This is a MapActivity, which will display our Google Map. There
* is a horizontal scroll view with all the tools available to the
* user. Each tool has its own View.
*/ 
public class Combat extends MapActivity implements OnClickListener {
	
	private static final String TAG = "Combat";
	private Context context;
	
	public PWLocationListener locationListener;
	public PWSensorListener sensorListener;
	public NetworkTask netTask;
	
	private ProgressDialog reloadProgressDialog;
	private int progressBarStatus = 100;
	
	public TextView tvScore;
	public TextView tvDump;
	public ViewGroup emptyView;
	private View viewMap;
	private View viewGun;
	private View viewMine;
	private View viewStats;
	private View viewLight;
	private Button buttonShoot;
	private Button buttonLight;
	private TextView tvStatsKills;
	private TextView tvStatsDeaths;
	private TextView tvStatsPlayers;
	private TextView tvStatsScores;
	private WebService mWebService;
	private Camera cam;
	private boolean boolLight = false;

	private MapView mapView;
	private MapController mapController;
	private List<Overlay> mapOverlays;
	
	private Handler uiHandler = new Handler();
	public Handler netTaskHandler;
	
	public Player player;
	
	private SQLiteDatabase db;
	private MySQLiteHelper dbHelper;
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setContentView(R.layout.combat);
		context = this;
		
		dbHelper = MySQLiteHelper.getInstance(getApplicationContext());
		db = dbHelper.getWritableDatabase();
		LinearLayout l = (LinearLayout)findViewById(R.id.topLayout);
    	l.setBackgroundColor(dbHelper.getBgColor(db));
		
		// Find who we are in the player list and make 'player' reference it
		PWApplication appState = (PWApplication)getApplicationContext();
		mWebService = WebService.getInstance(this);
		try {
			JSONObject jObject = mWebService.getId();
			player = appState.findPlayer(jObject.getInt("id"));
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		// Start the background network task that handles sending/receiving
		netTask = new NetworkTask(this);
		netTaskHandler = netTask.getHandler();
		netTask.execute();
		
		// Start listening to location(GPS) and sensor changes
		locationListener = new PWLocationListener(this);
		sensorListener = new PWSensorListener(this);
		locationListener.start();
		sensorListener.start();
		
		tvScore = (TextView)findViewById(R.id.tvScore);
		tvDump = (TextView)findViewById(R.id.tvDump);

		setupBackpack();
	}
	
	private void setupMap() {
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);
		mapController = mapView.getController();
		mapController.setZoom(20);
		
		mapOverlays = mapView.getOverlays();
	}
	
	private void setupBackpack() {
		Button b;
		
		findViewById(R.id.btnMap).setOnClickListener(this);
		findViewById(R.id.btnGun).setOnClickListener(this);
		findViewById(R.id.btnMine).setOnClickListener(this);
		findViewById(R.id.btnStats).setOnClickListener(this);
		findViewById(R.id.btnLight).setOnClickListener(this);
		emptyView = (ViewGroup) findViewById(R.id.emptyView);
		
		// Load and setup the map view
		viewMap = LayoutInflater.from(getBaseContext()).inflate(R.layout.backpack_map, emptyView, false);
		emptyView.addView(viewMap);
		setupMap();
		emptyView.removeView(viewMap);
		
		// Load and setup the gun view
		viewGun = LayoutInflater.from(getBaseContext()).inflate(R.layout.backpack_gun, emptyView, false);
		emptyView.addView(viewGun);
		buttonShoot = (Button)findViewById(R.id.buttonShoot);
		buttonShoot.setOnClickListener(backpackGunListener);
		emptyView.removeView(viewGun);
		
		// Load and setup the mine view
		viewMine = LayoutInflater.from(getBaseContext()).inflate(R.layout.backpack_mine, emptyView, false);
		emptyView.addView(viewMine);
		b = (Button)findViewById(R.id.btnMineLay);
		b.setOnClickListener(backpackMineListener);
		b = (Button)findViewById(R.id.btnMineDetonate);
		b.setOnClickListener(backpackMineListener);
		emptyView.removeView(viewMine);
		
		// Load and setup the stats view
		viewStats = LayoutInflater.from(getBaseContext()).inflate(R.layout.backpack_stats, emptyView, false);
		emptyView.addView(viewStats);
		tvStatsPlayers = (TextView)findViewById(R.id.tvStatsPlayers);
		tvStatsKills = (TextView)findViewById(R.id.tvStatsKills);
		tvStatsDeaths = (TextView)findViewById(R.id.tvStatsDeaths);
		tvStatsScores = (TextView)findViewById(R.id.tvStatsScores);
		emptyView.removeView(viewStats);
		
		// Load and setup the gun view
		viewLight = LayoutInflater.from(getBaseContext()).inflate(R.layout.backpack_light, emptyView, false);
		emptyView.addView(viewLight);
		buttonLight = (Button)findViewById(R.id.buttonLight);
		buttonLight.setOnClickListener(backpackLightListener);
		emptyView.removeView(viewLight);
		
		// Set default view when activity starts
		emptyView.addView(viewGun);
	}
	
	// Add a mine marker at (latitude,longitude)
	void addMineMarker(double[] pos) {
		Drawable drawable = this.getResources().getDrawable(R.drawable.marker_mine);
		Marker itemizedoverlay = new Marker(drawable, this);
		
		GeoPoint point = new GeoPoint((int)(pos[0] * 1E6),(int)(pos[1] * 1E6));
		OverlayItem overlayitem = new OverlayItem(point, "Mine Marker", "You layed a mine here!");

		itemizedoverlay.addOverlay(overlayitem);
		mapOverlays.add(itemizedoverlay);
		player.setMine(pos);
	}
	
	void clearMineMarkers() {
		mapOverlays.clear();
		player.detonateMines();
	}
	
	public void onClick(View v) {
		switch(v.getId()) {
		case R.id.btnMap:
			emptyView.removeView(findViewById(R.id.topView));
			emptyView.addView(viewMap);
			break;
		case R.id.btnGun:
			emptyView.removeView(findViewById(R.id.topView));
			emptyView.addView(viewGun);
			break;
		case R.id.btnMine:
			emptyView.removeView(findViewById(R.id.topView));
			emptyView.addView(viewMine);
			break;
		case R.id.btnStats:
			emptyView.removeView(findViewById(R.id.topView));
			emptyView.addView(viewStats);
			updateStats();
			break;
		case R.id.btnLight:
			emptyView.removeView(findViewById(R.id.topView));
			emptyView.addView(viewLight);
			break;
		}
	}
	
	public void updateStats() {
		PWApplication appState = ((PWApplication)getApplicationContext());
		tvStatsPlayers.setText("");
		tvStatsKills.setText("");
		tvStatsDeaths.setText("");
		tvStatsScores.setText("");
		for(Player p : appState.getPlayerList()) {
			tvStatsPlayers.append(p.getName()+"\n");
			tvStatsKills.append(p.getKills()+"\n");
			tvStatsDeaths.append(p.getDeaths()+"\n");
			tvStatsScores.append(p.getScore()+"\n");
		}
	}
	
	private OnClickListener backpackLightListener = new OnClickListener() {
		
	    public void onClick(View v) {
	    	switch(v.getId()) {
			case R.id.buttonLight:
				lightToggle();
				break;
			}
	    }
	};
	
	private void lightToggle() {
		if(!boolLight) {
			boolLight = true;
			// Check if light is available
			if(!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
				return;
			}
			
			cam = Camera.open();     
			Parameters p = cam.getParameters();
			p.setFlashMode(Parameters.FLASH_MODE_TORCH);
			cam.setParameters(p);
			cam.startPreview();
		} else {
			boolLight = false;
			cam.stopPreview();
			cam.release();
		}
	}
	
	private OnClickListener backpackMineListener = new OnClickListener() {
		
	    public void onClick(View v) {
	    	switch(v.getId()) {
			case R.id.btnMineLay:
				sendNetworkTaskMessage(UpdateType.UPDATE_MINE_LAY);
				Log.d(TAG, "Sent mine set message to NetTask");
				break;
			case R.id.btnMineDetonate:
				sendNetworkTaskMessage(UpdateType.UPDATE_MINE_DETONATE);
				Log.d(TAG, "Sent mines detonate message to NetTask");
				break;
			}
	    }
	};
	
	private OnClickListener backpackGunListener = new OnClickListener() {
		
	    public void onClick(View v) {
	    	switch(v.getId()) {
			case R.id.buttonShoot:
				Button button = (Button)v;
				progressBarStatus = 0;
				button.setEnabled(false);
				
				//sendNetTaskMessage(new UpdateMessage(MessageType.UPDATE_GUN_SHOT,player.getOrientation()));
				
				sendNetworkTaskMessage(UpdateType.UPDATE_GUN_SHOT);
				Log.d(TAG, "Sent shoot message to ClientTask");
				
				button.setText("Reloading...");
				startReload();
				break;
			}
	    }

	    private void startReload() {
			reloadProgressDialog = new ProgressDialog(context);
			reloadProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			reloadProgressDialog.setMessage("Reloading...");
			reloadProgressDialog.setCancelable(false);
			reloadProgressDialog.show();
			
			new Thread(new Runnable() {
				public void run() {
					while (progressBarStatus < 100) {
						progressBarStatus++;

						try {
							Thread.sleep(50);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						uiHandler.post(new Runnable() {
							public void run() {
								reloadProgressDialog.setProgress(progressBarStatus);
							}
						});
					}
					uiHandler.post(new Runnable() {
						public void run() {
							reloadProgressDialog.cancel();
							buttonShoot.setText("Shoot");
							buttonShoot.setEnabled(true);
						}
					});
				}
			}).start();
		}
	};
	
	void sendNetworkTaskMessage(int updateType) {
		Message msg = netTaskHandler.obtainMessage(updateType);
		msg.obj = updateType;
		netTaskHandler.sendMessage(msg);
	}

	void removeNetworkTaskMessages(int updateType) {
		netTaskHandler.removeMessages(updateType);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		locationListener.start();
		sensorListener.start();
	}

	@Override
	protected void onPause() {
		locationListener.stop();
		sensorListener.stop();
		
		try {
			mWebService.leaveMatch();
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		super.onStop();
		finish();
	}
	
	@Override
	protected void onStop() {
		locationListener.stop();
		sensorListener.stop();
		
		try {
			mWebService.leaveMatch();
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		super.onStop();
		finish();
	}
	
	void zoomToMyLocation() {
		double[] c = player.getPosition();
		GeoPoint p = new GeoPoint((int) (c[0] * 1E6),(int) (c[1] * 1E6));
 
        mapController.animateTo(p);
	}
	
	void gameOverAlert(String s) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Alert!");
		alert.setMessage(s);
		alert.setCancelable(false);
		alert.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				Combat.this.finish();
			}
		});
		alert.show();
	}
	
	void showAlert(String s) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Alert!");
		alert.setMessage(s);
		alert.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				
			}
		});
		alert.show();
	}
	
	@Override
    protected boolean isRouteDisplayed() {
        return false;
    }

	public void onClick(DialogInterface dialog, int which) {
		// TODO Auto-generated method stub
		
	}
}
